package com.hoshino.momochi.controller;

import com.alibaba.fastjson.JSON;
import com.hoshino.momochi.annotation.History;
import com.hoshino.momochi.annotation.IgnoreLogin;
import com.hoshino.momochi.config.Trie.Trie;
import com.hoshino.momochi.model.DTO.BlogDTO;
import com.hoshino.momochi.model.DTO.SortBlog;
import com.hoshino.momochi.model.domain.Blog;
import com.hoshino.momochi.model.domain.Focus;
import com.hoshino.momochi.service.*;
import com.hoshino.momochi.util.CodeEnum;
import com.hoshino.momochi.util.JsonResponse;
import com.hoshino.momochi.util.PageCheck;
import com.hoshino.momochi.util.SomeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;

@RestController
@Slf4j
public class BlogController {

    @Autowired
    private BlogService blogService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private SseService sseService;

    @Autowired
    private BlogTagService blogTagService;

    @Autowired
    private FocusService focusService;

    @Autowired
    private BlogLikeService blogLikeService;

    @Autowired
    private CollectionBlogService collectionBlogService;

    @Autowired
    private BlogViewsService blogViewsService;

    @Autowired
    private Trie trie;

    private final String USER_ID = CodeEnum.USERID.getMessage();

    private final String BLOG_ID = CodeEnum.BLOGID.getMessage();

    /**
     * 获取在 缓存的 博客 部分信息
     *
     * @param request
     * @param blogDTO 需求字段 need_page 获取指定页 博客 简要信息 page_size(可以为null)
     * @return
     */
    @RequestMapping("api/blog/getcache")
    @IgnoreLogin
    public JsonResponse getCacheBlog(HttpServletRequest request, @RequestBody BlogDTO blogDTO) {
//        String count = redisService.getCacheBlogN();
//        List<Blog> bl = JSON.parseArray(count, Blog.class);
        List<Blog> bl = blogService.findAllBriefBlogs();
        return JsonResponse.success(PageCheck.pageCheck(SomeUtils.sortByCreateTime(bl), blogDTO.getNeed_page(), blogDTO.getPage_size()), CodeEnum.SUCCESS.getMessage());
    }

    /**
     * 模糊搜索
     *
     * @param request
     * @param blogDTO 可选传入字段 search_blogs, need_page, page_size(可以为null)
     * @return
     */
    @RequestMapping("api/blog/search")
    @IgnoreLogin
    public JsonResponse searchLikeBlog(HttpServletRequest request, @RequestBody BlogDTO blogDTO) {
        String count = redisService.getCacheBlogN();
        List<Blog> bl = JSON.parseArray(count, Blog.class);
        String searchS = blogDTO.getSearch_blogs();
        List<Blog> blogList = bl.stream().filter(s -> Pattern.matches(".*" + searchS + ".*", s.getBlogName()) || Pattern.matches(".*" + searchS + ".*", s.getBrief()) || (!s.getTags().stream().filter(q -> Pattern.matches(searchS, q)).toList().isEmpty())).toList();
        Integer need_page = blogDTO.getNeed_page();
        Integer page_size = blogDTO.getPage_size();
        return JsonResponse.success(PageCheck.pageCheck(blogList, need_page, page_size), CodeEnum.SUCCESS.getMessage());
    }

    /**
     * 使用此方法 getCacheBlog方法是指定页数进行返回，当前getCacheBlogNO 返回全部博客简要信息
     *
     * @param request
     * @return
     */
    @RequestMapping("api/blog/getCacheBlog")
    @IgnoreLogin
    public JsonResponse getCacheBlogNO(HttpServletRequest request) {
        String count = redisService.getCacheBlogN();
        return JsonResponse.success(JSON.parseArray(count, Blog.class), CodeEnum.SUCCESS.getMessage());
    }

    /**
     * 根据用户 ID 查找该用户的 所有博客 （不包含评论以及正文内容信息）
     *
     * @param request
     * @param blogDTO 需求字段 user_id need_page page_size(可以为null)
     * @return
     */
    @RequestMapping("api/blog/getByUid")
    @IgnoreLogin
    public JsonResponse getByUserId(HttpServletRequest request, @RequestBody BlogDTO blogDTO) {
        return Objects.isNull(blogDTO.getUser_id()) ? null : JsonResponse.success(PageCheck.pageCheck(SomeUtils.sortByCreateTime(blogService.findBlogsByUser(blogDTO.getUser_id())), blogDTO.getNeed_page(), blogDTO.getPage_size()), CodeEnum.SUCCESS.getMessage());
    }

    /**
     * 根据 博客 id 获取 博客详细信息内容
     *
     * @param blogDTO 需求字段 blog_id
     * @return
     */
    @RequestMapping("api/blog/getById")
    @History
    @IgnoreLogin
    public JsonResponse getByBlogId(HttpServletRequest request, @RequestBody BlogDTO blogDTO) {
        Long uid = (Long) request.getAttribute(USER_ID);
        Long blogId = blogDTO.getBlog_id();
        Blog blog = null;
        if (Objects.isNull(blogId)) {
            return JsonResponse.success(CodeEnum.NOTNULL.getCode(), CodeEnum.NOTNULL.getMessage());
        }
        blog = blogService.findCompleteById(blogId); // 获取博客详细信息
        if (Objects.isNull(blog)) {
            return JsonResponse.success(CodeEnum.NOTEXIST.getCode(), CodeEnum.NOTEXIST.getMessage());
        }
        //blogService.updateViews(blog); // 更新浏览量
        blogViewsService.increaseBlogViews(blog.getId(), 1L); // 更新浏览量
        blog.setViews(blogViewsService.getBlogViews(blog.getId()));
        //redisService.BlogUpdateCache(); // 更新缓存
        request.setAttribute(BLOG_ID, blogId); // 设置 blog_id 历史记录
        Long authorId = blog.getUserId();
        if (Objects.nonNull(blogLikeService.checkUserLikeBlog(uid, blogId))) {
            blog.setYouLike(true);
        }
        if (Objects.nonNull(collectionBlogService.findUserIsStar(uid, blogId))) {
            blog.setYouStar(true);
        }
        if (uid != authorId && Objects.nonNull(focusService.getLocalUserByUserId(uid, authorId))) {
            blog.setYouFocus(true);
        }
        return JsonResponse.success(blog, CodeEnum.SUCCESS.getMessage());
    }

    /**
     * 新增
     *
     * @param request
     * @param blogDTO 需求字段 博客名称blog_name  博客正文内容content, 博客标签列表tag_ids
     * @return
     */
    @RequestMapping("api/blog/add")
    public JsonResponse addUserBlog(HttpServletRequest request, @RequestBody BlogDTO blogDTO) {
        Long uid = (Long) request.getAttribute(USER_ID);
        String blogName = blogDTO.getBlog_name();
        String content = blogDTO.getContent();
        String brief = blogDTO.getBrief();
        try {
            content = trie.haveAsyncSensitiveWordReplace(content).get(); // 敏感词替换
            brief = trie.haveAsyncSensitiveWordReplace(brief).get();
        } catch (Exception e) {
            log.info("Trie方法错误{}", e.getMessage());
        }


        if (!StringUtils.isNotBlank(blogName) || !StringUtils.isNotBlank(content)) {
            return JsonResponse.success(CodeEnum.ERROR.getCode(), CodeEnum.ERROR.getMessage());
        }

        Date date = new Date();
        Blog blog = new Blog();
        blog.setUserId(uid).setBlogName(blogName).setContent(content).setBrief(brief).setCreateTime(date).setLastUpdateTime(date);

        blogService.addUserBlog(blog);

        // 添加标签
        log.info("新增博客id:{}", blog.getId());
        List<Long> ids = blogDTO.getTag_ids();
        if (Objects.nonNull(ids) && ids.size() > 0) {
            blogTagService.addListBlogTag(blog.getId(), ids);
        }

        // 添加浏览量
        blogViewsService.addNewBlog(blog.getId());

        // update redis
        redisService.BlogUpdateCache();

        // 新增博客 需要向 粉丝进行 消息发送
        Focus focus = new Focus();
        focus.setLocalId(uid); // 我作为被关注者
        List<Long> focus_ids = focusService.getFocus(focus);
        for (var pullId : focus_ids) {
            sseService.sendMessage(uid, pullId, "我有一篇新的博客，快来看看吧");
        }
        return JsonResponse.success(CodeEnum.SUCCESS.getCode(), CodeEnum.SUCCESS.getMessage());
    }


    /**
     * 修改指定博客
     *
     * @param request
     * @param blogDTO 需求字段 可为NULL blog_name content blog_id brief
     * @return
     */
    @RequestMapping("api/blog/update")
    public JsonResponse updateUserBlog(HttpServletRequest request, @RequestBody BlogDTO blogDTO) {
        Long uid = (Long) request.getAttribute(USER_ID);
        Date date = new Date();
        String blogName = blogDTO.getBlog_name();
        String content = blogDTO.getContent();
        String brief = blogDTO.getBrief();
        if (!StringUtils.isNotBlank(blogName)) {
            blogName = null;
        }
        if (!StringUtils.isNotBlank(content)) {
            content = null;
        }
        if (!StringUtils.isNotBlank(brief)) {
            brief = null;
        }
        Long id = blogDTO.getBlog_id();
        Blog blog = new Blog();
        blog.setLastUpdateTime(date).setUserId(uid).setContent(content).setBlogName(blogName).setBrief(brief).setId(id);
        blogService.updateUserBlog(blog);
        redisService.BlogUpdateCache();
        return JsonResponse.success(CodeEnum.SUCCESS.getCode(), CodeEnum.SUCCESS.getMessage());
    }

    /**
     * 删除当前用户指定的博客
     *
     * @param request
     * @param blogDTO 需求字段 blog_id
     * @return
     */
    @RequestMapping("api/blog/delUserBlog")
    public JsonResponse delUserBlog(HttpServletRequest request, @RequestBody BlogDTO blogDTO) {
        Long uid = (Long) request.getAttribute(USER_ID);
        Long bid = blogDTO.getBlog_id();
        if (Objects.isNull(bid)) {
            return JsonResponse.success(CodeEnum.NOTNULL.getCode(), CodeEnum.NOTNULL.getMessage());
        }
        blogService.delUserBlog(uid, bid);
        redisService.BlogUpdateCache();
        return JsonResponse.success(CodeEnum.SUCCESS.getCode(), CodeEnum.SUCCESS.getMessage());
    }

    /**
     * 获取当前登录用户 关注的 用户 的 博客
     *
     * @param request
     * @param blogDTO need_page, page_size(可以为null)
     * @return
     */
    @RequestMapping("api/blog/getLocalBlog")
    public JsonResponse getLocalBlog(HttpServletRequest request, @RequestBody BlogDTO blogDTO) {
        Long uid = (Long) request.getAttribute(USER_ID);
        List<Blog> bl = blogService.getLocalBlog(uid);
        return JsonResponse.success(PageCheck.pageCheck(SomeUtils.sortByCreateTime(bl), blogDTO.getNeed_page(), blogDTO.getPage_size()), CodeEnum.SUCCESS.getMessage());
    }

    /**
     * 排行榜
     *
     * @return
     */
    @RequestMapping("api/blog/getBlogSort")
    @IgnoreLogin
    public JsonResponse getBlogSort() {
        SortBlog sortBlog = new SortBlog();
        try {
            sortBlog.setMaxStarBlog(blogService.getMaxStarBlog().get());
            sortBlog.setMaxLikeBlog(blogService.getMaxLikeBlog().get());
            sortBlog.setMaxViewBlog(blogService.getMaxViewBlog().get());
        } catch (Exception e) {

        }
        return JsonResponse.success(sortBlog);
    }
}
